﻿/******************************************************************************/
#include "stdafx.h"
#include "Main.h"
/******************************************************************************/
static void WindowFadeOut(Window &window) {window.fadeOut();}
/******************************************************************************/
STRUCT(NewChr , GuiObjs)
//{
   Tabs Class;

   static void Create(NewChr &nc)
   {
      ChrCreateRequest ccr;
      ccr.name=nc.getTextLine("name")();
      ccr.obj =((nc.Class()==0) ? Game::Objs("obj/chr/warrior/0.obj") : (nc.Class()==1) ? Game::Objs("obj/chr/human/0.obj") : NULL);
      ccr.size=1.8f;
      if(!ValidName(ccr.name))Gui.msgBox("Error", "Invalid Character Name.\nIt must be between 1-32 characters,\nIt may not start with a space or .\nIt may not contain following characters: \\ / : * ? \" < > | @");else
      if(!ccr.obj            )Gui.msgBox("Error", "Please select character class.");else
      if(!ccr.valid        ())Gui.msgBox("Error", "Invalid character data.");else
      {
         ClientSendCreateChr      (Server, ccr);
         ClientSendListChrsRequest(Server     ); // immediately after creating new character request new list of characters from the server
      }
   }

   void create()
   {
      CChar *class_text[]=
      {
         L"Warrior",
         L"Human",
      };

      load("gui/create character.gobj"); hide(); Gui+=T; Window &win=getWindow(""); win.button[2].func(WindowFadeOut, win).show();

     *getCustom("class" ).parent()+=Class.create(getCustom("class").rect, 0, class_text, Elms(class_text));
      getButton("create").func(Create, T);
   }
}NC;
/******************************************************************************/
STRUCT(DelChr , GuiObjs)
//{
   Str chr_name;

   static void Del(DelChr &dc)
   {
      ClientSendDeleteChr      (Server, dc.chr_name, dc.getTextLine("pass")());
      ClientSendListChrsRequest(Server); // immediately after deleting character request new list of characters from the server
   }

   void create(Str name)
   {
      chr_name=name;
      load("gui/delete character.gobj"); Gui+=T; Window &win=getWindow(""); win.button[2].func(WindowFadeOut, win).show();
      getButton("ok").func(Del, T);
   }
}DC;
/******************************************************************************/
STRUCT(ChrSelection , Window)
//{
   struct Chr
   {
      Str     name;
      MeshPtr mesh;

      void create(NetChr &nc)
      {
         name=nc.name;
         mesh=nc.mesh;
      }
   };
   Region    region;
   Memc<Chr> chars;
   List<Chr> list;
   Button    ok, New, Del;

   static void OK (ChrSelection &cs) {if(Chr *chr=cs.list())ClientSendEnterGame(Server, chr->name);}
   static void NEW(ChrSelection &cs) {NC.activate();}   
   static void DEL(ChrSelection &cs) {if(Chr *chr=cs.list())DC.create(chr->name);}   

   Window& del()
   {
      chars.del();
      list .del();
      return super::del();
   }
   void create()
   {
      ListColumn lc[]=
      {
         ListColumn(MEMBER(Chr, name), LCW_PARENT, L"Name"),
      };

      Gui+=super::create(Rect_R(D.w()-0.1f, 0, 1, 1.5f), "Select Character");
      T+=region.create(Rect_U(crect.w()*0.5f, -0.1f, 0.8f, 1.0f));
      region+=list.create(); list.setColumns(lc, Elms(lc), true); list.cur_mode=LCM_ALWAYS;
      T+=ok .create(Rect_D(crect.w()*0.50f, -crect.h()+0.15f, 0.8f, 0.07f), "OK"    ).func(OK , T);
      T+=New.create(Rect_D(crect.w()*0.25f, -crect.h()+0.08f, 0.3f, 0.06f), "New"   ).func(NEW, T);
      T+=Del.create(Rect_D(crect.w()*0.75f, -crect.h()+0.08f, 0.3f, 0.06f), "Delete").func(DEL, T);
   }
   virtual void update(C GuiPC &gpc)
   {
      super::update(gpc);

      if(Gui.ms()==&list && Ms.bd(0))OK(T);
   }
}CS;
/******************************************************************************/
static void Logout(Ptr)
{
   Logout();
   StateLogin.set(0.2f);
}
Button LogoutButton;
/******************************************************************************/
Bool InitSelectChr()
{
   ClientSendListChrsRequest(Server);
   CS.create();
   NC.create();
   Gui+=LogoutButton.create(Rect_RD(D.w()-0.1f, -D.h()+0.1f, 0.3, 0.05), "Logout").func(Logout);
   Sky.clear();
   AstrosDraw=false;
   return true;
}
void ShutSelectChr()
{
   CS.del();
   NC.del();
   DC.del();
   LogoutButton.del();
   AstrosDraw=true;
}
/******************************************************************************/
Bool UpdateSelectChr()
{
   Gui.update();

   // check server state
   if(Server.state()!=CONNECT_GREETED){Gui.msgBox("Error", "Connection Lost"); StateSelectServer.set(0.2f);}

   // check if any data received from server
   if(Server.receive(0))switch(Server.data.getByte())
   {
      case CS_LIST_CHRS: // server sent us a list of characters
      {
         Memc<NetChr> chrs; ClientRecvListChrs(Server.data, chrs);
         CS.chars .setNum (chrs.elms()); REPAO(CS.chars).create(chrs[i]);
         CS.list  .setData(CS.chars, NULL, true);
         CS.region.setSize();
         Time.skipUpdate();
      }break;

      case CS_CREATE_CHR:
      {
         CHR_CREATE_RESULT result; ClientRecvCreateChr(Server.data, result);
         switch(result)
         {
            case CHR_CREATE_NOT_LOGGED_IN:            Gui.msgBox("Error", "Can't create character when not logged in"                ); break;
            case CHR_CREATE_NO_ROOM      :            Gui.msgBox("Error", "Your account has reached the maximum amount of characters"); break;
            case CHR_CREATE_INVALID_DATA :            Gui.msgBox("Error", "Character creation failed because of invalid data"        ); break;
            case CHR_CREATE_NAME_TAKEN   :            Gui.msgBox("Error", "Name already taken"                                       ); break;
            case CHR_CREATE_OK           : NC.hide(); Gui.msgBox(""     , "Character created successfully"                           ); break;
         }
      }break;

      case CS_ENTER_GAME: {Bool ok; ClientRecvEnterGame(Server.data, ok, ChrData); if(ok)StateGame.set(1.0f);} break;
   }

   return true;
}
/******************************************************************************/
void RenderSelectChr()
{
   switch(Renderer())
   {
      case RM_PREPARE:
      {
         LightDir(!(Cam.matrix.x+Cam.matrix.z-Cam.matrix.y)).add(false);

         if(ChrSelection::Chr *chr=CS.list())
            if(chr->mesh)chr->mesh->draw(MatrixIdentity);
      }break;
   }
}
void DrawSelectChr()
{
   Cam.setSpherical(Vec(0), Time.appTime(), 0, 0, 1.5f);
   Cam+=Cam.matrix.x*0.6f; Cam.updateVelocities().set();
   Renderer(RenderSelectChr);
   Gui.draw();
}
/******************************************************************************/
State StateSelectChr(UpdateSelectChr, DrawSelectChr, InitSelectChr, ShutSelectChr);
/******************************************************************************/
